package com.longe.netty.chat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

public class NettyChatServerHandler extends SimpleChannelInboundHandler<String> {

    //定义一个channel组
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 一旦建立连接，handlerAdded第一个被执行
     *
     * @param ctx
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {

        Channel channel = ctx.channel();
        //通知其他客户端
        channelGroup.writeAndFlush(channel.remoteAddress() + " 加入了聊天室");
        //当前channel加入channelGroup
        channelGroup.add(channel);
    }

    /**
     * 断开连接
     *
     * @param ctx
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush(channel.remoteAddress() + " 离开了");
        System.err.println("channelGroup size = " + channelGroup.size());
    }

    /**
     * 活动状态
     *
     * @param ctx
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        //提示上线
        System.err.println(ctx.channel().remoteAddress() + " 上线了~");
    }

    /**
     * 非活动状态
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        //提示离线
        System.err.println(ctx.channel().remoteAddress() + " 离线了~");
    }

    /**
     * 异常
     *
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        //关闭通道
        ctx.close();
    }

    /**
     * 读取信息
     *
     * @param ctx
     * @param msg
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {

        //获取当前channel
        Channel channel = ctx.channel();
        channelGroup.forEach(ch -> {
            if (ch != channel) { //不是当前channel,转发信息
                ch.writeAndFlush(channel.remoteAddress() + " 发送了消息: " + msg);
            }
        });
    }
}
